package gui.panels;

import config.AppConfig;
import config.OtherConfig;
import config.ServerConfig;
import domain.constants.OperationType;
import domain.entities.OperationRecord;
import domain.services.OperationRecordDomainService;
import eventbus.PageEventBus;
import eventbus.PageEvents;
import gui.SubPanel;
import util.DialogHelper;
import util.DifferentiationHelper;
import util.StringValidator;

import javax.swing.*;
import java.awt.*;
import java.util.Arrays;
import java.util.stream.Collectors;

public class SystemConfigSubPanel extends SubPanel {

    JLabel wsPathLabel = new JLabel("WS路径:");
    JTextField wsPathInput = new JTextField();

    JLabel wsPortLabel = new JLabel("WS端口:");
    JTextField wsPortInput = new JTextField();

    JLabel themeLabel = new JLabel("主题:");
    JComboBox<String> themeInput = new JComboBox<>();

    JLabel fontLabel = new JLabel("字体:");
    JComboBox<String> fontInput = new JComboBox<>();

    JLabel languageLabel = new JLabel("语言:");
    JComboBox<String> languageInput = new JComboBox<>();

    JButton saveConfigBtn = new JButton("保存配置");
    JButton applyConfigBtn = new JButton("重启应用配置");

    public SystemConfigSubPanel() {

        wsPathLabel.setBounds(100, 60, 60, 35);
        wsPathInput.setBounds(165, 60, 250, 35);

        wsPortLabel.setBounds(100, 120, 60, 35);
        wsPortInput.setBounds(165, 120, 250, 35);

        themeLabel.setBounds(100, 180, 60, 35);
        themeInput.setBounds(165, 180, 200, 35);
        Arrays.stream(UIManager.getInstalledLookAndFeels())
                .collect(Collectors.toList())
                .forEach(x -> themeInput.addItem(x.getName()));

        fontLabel.setBounds(100, 240, 60, 35);
        fontInput.setBounds(165, 240, 200, 35);
        GraphicsEnvironment ge = GraphicsEnvironment.getLocalGraphicsEnvironment();
        String[] fontames = ge.getAvailableFontFamilyNames();
        for (int i = 0; i < fontames.length; i++) {
            fontInput.addItem(fontames[i]);
        }

        languageLabel.setBounds(100, 300, 60, 35);
        languageInput.setBounds(165, 300, 200, 35);
        languageInput.addItem("English");
        languageInput.addItem("Chinese");

        saveConfigBtn.setBounds(100, 360, 120, 35);
        applyConfigBtn.setBounds(250, 360, 120, 35);
        this.add(wsPathLabel);
        this.add(wsPathInput);
        this.add(wsPortLabel);
        this.add(wsPortInput);
        this.add(themeLabel);
        this.add(themeInput);
        this.add(fontLabel);
        this.add(fontInput);
        this.add(languageLabel);
        this.add(languageInput);
        this.add(saveConfigBtn);
        this.add(applyConfigBtn);

        wsPathInput.setText(AppConfig.ServerConfig.getWebsocketsPath());
        wsPortInput.setText(String.valueOf(AppConfig.ServerConfig.getPort()));
        themeInput.setSelectedItem(AppConfig.OtherConfig.getTheme());
        fontInput.setSelectedItem(AppConfig.OtherConfig.getFontFamily());
        languageInput.setSelectedItem(AppConfig.OtherConfig.getLanguage());

        saveConfigBtn.addActionListener(e -> {
            if (saveConfig()) {
                DialogHelper.showSuccessDialog("保存成功,配置将在下一次启动后生效");
            }
        });
        applyConfigBtn.addActionListener(e -> {
            if (saveConfig()) {
                PageEventBus.publish(PageEvents.APP_RELOAD_EVENT);
            } else {
                DialogHelper.showSuccessDialog("保存失败");
            }
        });

    }

    public boolean saveConfig() {
        try {
            //收集配置信息
            String wsPath = wsPathInput.getText();
            int port = Integer.parseInt(wsPortInput.getText());
            String languageName = languageInput.getSelectedItem().toString();
            String fontName = fontInput.getSelectedItem().toString();
            String themeName = themeInput.getSelectedItem().toString();
            //配置校验
            if (StringValidator.isBlank(wsPath)) {
                DialogHelper.showWaringDialog("ws路径不允许为空");
                return false;
            }
            if (!(port >= 5001 && port <= 65535)) {
                DialogHelper.showWaringDialog("端口号范围必须为5001-65535之间");
                return false;
            }
            //构建配置对象
            OtherConfig otherConfig = new OtherConfig(fontName, themeName, languageName);
            ServerConfig serverConfig = new ServerConfig(wsPath, port);
            String otherDiff = DifferentiationHelper.diff(AppConfig.OtherConfig, otherConfig);
            String serverDiff = DifferentiationHelper.diff(AppConfig.ServerConfig, serverConfig);
            //差异化比较和记录
            if (!"".equals(otherDiff)) {
                AppConfig.setOtherConfig(otherConfig);
                OperationRecordDomainService.Instance.add(new OperationRecord(OperationType.UPDATE_OTHER_CONFIG, otherDiff));
            }
            if (!"".equals(serverDiff)) {
                AppConfig.setServerConfig(serverConfig);
                OperationRecordDomainService.Instance.add(new OperationRecord(OperationType.UPDATE_SERVER_CONFIG, serverDiff));
            }
            AppConfig.initConfig();
            return true;
        } catch (NumberFormatException numberFormatException) {
            DialogHelper.showWaringDialog("端口号只能为数字");
        } catch (Exception exception) {
            DialogHelper.showFailDialog(exception.getMessage());
        }
        return false;
    }
}
